/**
 * @author liangxi
 * @since 2023/12/21
 */

#ifndef DESIGNPATTERN_DUCK_H
#define DESIGNPATTERN_DUCK_H

#include <memory>
#include "../Behavior/Fly/FlyBehavior.h"
#include "../Behavior/Quack/QuackBehavior.h"

namespace Strategy {

    class Duck {
    public:
        Duck() = default;

        explicit Duck(const std::shared_ptr<FlyBehavior> &flyBehavior,
                      const std::shared_ptr<QuackBehavior> &quackBehavior)
                : flyBehavior(flyBehavior), quackBehavior(quackBehavior) {}

        Duck(const Duck &rhs) {

            if (this != &rhs) {
                auto tmp = rhs.flyBehavior.get();
                //  if(dynamic_cast<type>(tmp))
                // this->flyBehavior = std::make_shared<FlyBehavior>(rhs.flyBehavior.get());
                //this->flyBehavior = rhs.flyBehavior.get();
            }
        }

        virtual ~Duck() = default;

        void setFlyBehavior(const std::shared_ptr<FlyBehavior> &behavior) {
            Duck::flyBehavior = behavior;
        }

        void setQuackBehavior(const std::shared_ptr<QuackBehavior> &behavior) {
            Duck::quackBehavior = behavior;
        }

        void performFly() {
            flyBehavior->fly();
        }

        void performQuack() {
            quackBehavior->quack();
        }

        virtual void display() = 0;

    private:
        std::shared_ptr<FlyBehavior> flyBehavior{nullptr};
        std::shared_ptr<QuackBehavior> quackBehavior{nullptr};
    };

} // Strategy

#endif //DESIGNPATTERN_DUCK_H
